package com.briup.pts.service.impl;

import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.briup.pts.entity.ManagerAnimal;
import com.briup.pts.entity.ManagerAnimalExample;
import com.briup.pts.entity.ManagerBatch;
import com.briup.pts.entity.ManagerHurdles;
import com.briup.pts.entity.extend.ManagerAnimalExt;
import com.briup.pts.exception.ServiceException;
import com.briup.pts.mapper.ManagerAnimalMapper;
import com.briup.pts.mapper.ManagerBatchMapper;
import com.briup.pts.mapper.ManagerHurdlesMapper;
import com.briup.pts.mapper.extend.ManagerAnimalExtMapper;
import com.briup.pts.result.ResultCode;
import com.briup.pts.service.ManagerAnimalService;
import com.briup.pts.utils.RandomStringGenerator;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.List;

@Service
public class ManagerAnimalServiceImpl implements ManagerAnimalService {
    @Autowired
    ManagerAnimalMapper managerAnimalMapper;
    @Autowired
    ManagerBatchMapper managerBatchMapper;
    @Autowired
    ManagerHurdlesMapper managerHurdlesMapper;
    @Autowired
    ManagerAnimalExtMapper managerAnimalExtMapper;

    @Override
    public PageInfo<ManagerAnimalExt> findByPage(Integer pageNum, Integer pageSize, String aHealthy, String aGender) {
        PageHelper.startPage(pageNum, pageSize);
        return new PageInfo<>(managerAnimalExtMapper.selectAnimalRelated(aHealthy, aGender));
    }

    @Override
    @Transactional
    public void saveOrUpdate(ManagerAnimal animal) {
        //1.参数校验,体重不为空(其他字段也非空，前端已处理，此处不需要处理)
        if (animal == null || !StringUtils.hasText(animal.getAWeight())) {
            throw new ServiceException(ResultCode.PARAM_IS_EMPTY);
        }

        //2.判断栏圈是否有效存在
        // 新栏圈编号
        String aHurdlesIdNew = animal.getAHurdlesId();
        ManagerHurdles hurdlesNew = managerHurdlesMapper.selectByPrimaryKey(aHurdlesIdNew);
        if (hurdlesNew == null) {
            throw new ServiceException(ResultCode.HURDLES_NOT_EXIST);
        }

        //3.添加或者修改动物信息
        String aAnimalId = animal.getAAnimalId();
        if (StringUtils.hasText(aAnimalId)) {
            //3.1 有id->更新操作
            // a.根据id查询动物信息
            ManagerAnimal animalFromDB = managerAnimalMapper.selectByPrimaryKey(aAnimalId);
            if (animalFromDB == null)
                throw new ServiceException(ResultCode.ANIMAL_NOT_EXIST);
            // b.修改动物信息
            int result = managerAnimalMapper.updateByPrimaryKey(animal);
            if (result == 0)
                throw new ServiceException(ResultCode.FAIL + "修改动物信息失败");
            // c.判断是否修改了栏圈信息
            String aHurdlesIdOld = animalFromDB.getAHurdlesId();
            if (!aHurdlesIdOld.equals(aHurdlesIdNew)) {
                //动物栏圈发生改变
                // 1.新栏圈动物数量 + 1，并重置空满状态
                // 动物数量 + 1
                Integer hSaved = hurdlesNew.getHSaved();
                hurdlesNew.setHSaved(hSaved + 1);
                // 重置新栏圈空满状态
                if (hSaved + 1 == hurdlesNew.getHMax()) {
                    hurdlesNew.setHFull("已满");
                }
                // 执行更新操作
                managerHurdlesMapper.updateByPrimaryKey(hurdlesNew);
                // 2.老栏圈动物数量 - 1，并重置空满状态
                ManagerHurdles hurdlesOld = managerHurdlesMapper.selectByPrimaryKey(aHurdlesIdOld);
                // 动物数量 - 1
                hSaved = hurdlesOld.getHSaved();
                hurdlesOld.setHSaved(hSaved - 1);
                // 重置老栏圈空满状态
                if ("已满".equals(hurdlesOld.getHFull())) {
                    hurdlesOld.setHFull("未满");
                }
                // 执行更新
                managerHurdlesMapper.updateByPrimaryKey(hurdlesOld);
            }
        } else {
            // 3.2 无id->新增操作
            // a.批次有效判断
            ManagerBatch batchFromDB = managerBatchMapper.selectByPrimaryKey(animal.getABatchId());
            if (batchFromDB == null) {
                throw new ServiceException(ResultCode.BATCH_NOT_EXIST);
            }
            // b.根据批次检疫状态，设置动物的养殖状态
            String bQuarantine = batchFromDB.getBQuarantine();
            if ("已检疫".equals(bQuarantine)) {
                animal.setAStatus("已检疫");
            } else {
                animal.setAStatus("养殖中");
            }
            // c.添加动物信息

            animal.setAAnimalId(UUID.randomUUID().toString().replace(" "," "));
            int result = managerAnimalMapper.insert(animal);
            if (result == 0)
                throw new ServiceException(ResultCode.FAIL);
            // d.对应栏圈 动物数量 + 1，存储状态重置
            Integer hSaved = hurdlesNew.getHSaved();
            hurdlesNew.setHSaved(hSaved + 1);
            if (hSaved + 1 == hurdlesNew.getHMax()) {
                hurdlesNew.setHFull("已满");
            }
            managerHurdlesMapper.updateByPrimaryKey(hurdlesNew);
        }
    }

    @Override
    @Transactional
    public void addOrEditAnimal(ManagerAnimal animal) {
        String animalId = animal.getAAnimalId();
        if (StrUtil.isEmpty(animalId)) {
            // 新增操作
            // 0、动物表中的主键不是自增长的，是程序员需要依据主键生成策略完成的
            // 本次主键生成策略为UUID去除-的部分,使用的是huTools的工具
//            UUID.randomUUID();
            animal.setAAnimalId(IdUtil.simpleUUID());

            // 1、根据批次的状态来定义动物的状态
            String aBatchId = animal.getABatchId();
            ManagerBatch managerBatch = managerBatchMapper.selectByPrimaryKey(aBatchId);
            // 获取是否检疫的状态
            String bQuarantine = managerBatch.getBQuarantine();
            if ("已检疫".equals(bQuarantine)) {
                animal.setAStatus("已检疫");
            } else if ("未检疫".equals(bQuarantine)) {
                animal.setAStatus("养殖中");
            } else {
                throw new ServiceException(ResultCode.DATA_IS_EMPTY);
            }
            // 执行插入逻辑
            int insert = managerAnimalMapper.insert(animal);
            if (insert == 0) {
                // 插入失败
                throw new ServiceException(ResultCode.FAIL + "插入animal失败");
            }

            // 2、根据动物所属栏圈，查询当前容量和最大容量
            String aHurdlesId = animal.getAHurdlesId();
            ManagerHurdles managerHurdles = managerHurdlesMapper.selectByPrimaryKey(aHurdlesId);
            // 当前栏圈的已有容量
            Integer hSaved = managerHurdles.getHSaved();
            // 当前栏圈的最大容量
            Integer hMax = managerHurdles.getHMax();
            // +1
            Integer hCurr = hSaved + 1;
            // 提前准备一个用于更新的栏圈对象
            ManagerHurdles curr = new ManagerHurdles();
            curr.setHId(managerHurdles.getHId());
            curr.setHSaved(hCurr);
            // 判断
            if (hCurr.equals(hMax)) {
                // 已满
                curr.setHFull("已满");
            } // 未满
            // 3、根据容量是否达到最大，来修改栏圈的状态
            managerHurdlesMapper.updateByPrimaryKeySelective(curr);

        } else {
            // 修改操作
            managerAnimalMapper.updateByPrimaryKeySelective(animal);
            // 1、通过动物的id查询原来的动物信息
            ManagerAnimal managerAnimal = managerAnimalMapper.selectByPrimaryKey(animalId);

            // 2、如果原来动物信息存在，保存下来栏圈id
            if (managerAnimal == null) {
                // 报错为修改时查询的动物信息不存在
                throw new ServiceException(ResultCode.DATA_NONE + "修改时查询的动物信息不存在");
            }
            String oldId = managerAnimal.getAHurdlesId();

            // 3、判断传递的动物信息中有没有修改栏圈
            String newHid = animal.getAHurdlesId();
            if (!oldId.equals(newHid)) {
                // 3.5、当更新栏圈成功之后，在执行4
                // 转出栏圈
                ManagerHurdles oldHurdles1 = managerHurdlesMapper.selectByPrimaryKey(oldId);
                ManagerHurdles h1update = new ManagerHurdles();
                h1update.setHId(oldHurdles1.getHId());
                // 栏圈数量减一
                int h1Curr = oldHurdles1.getHSaved() - 1;
                h1update.setHSaved(h1Curr);
                if (h1Curr < 1) {
                    h1update.setHFull("未满");
                }

                // 转入栏圈
                ManagerHurdles h2 = managerHurdlesMapper.selectByPrimaryKey(newHid);
                ManagerHurdles h2update = new ManagerHurdles();
                h2update.setHId(newHid);
                // 转入栏圈数量 + 1
                Integer h2Curr = h2.getHSaved() + 1;
                h2update.setHSaved(h2Curr);
                // 判断转入栏圈是否已满
                if (h2Curr.equals(h2.getHMax())) {
                    h2update.setHFull("已满");
                }

                // 4、如果修改了，那更新两个栏圈的状态（是否已满）、已存数量
                // 更新栏圈状态
                managerHurdlesMapper.updateByPrimaryKeySelective(h1update);
                managerHurdlesMapper.updateByPrimaryKeySelective(h2update);
            } else {
                // 直接更新
                int i = managerAnimalMapper.updateByPrimaryKeySelective(animal);
                if (i == 0) {
                    // 动物更新失败
                    throw new ServiceException(ResultCode.FAIL + "动物更新失败");
                }
            }
        }
    }

    @Override
    @Transactional
    public void removeById(String id) {
        // 删除时修改动物所属栏圈的容量减一，原来已满，修改为未满
        ManagerAnimal managerAnimal = managerAnimalMapper.selectByPrimaryKey(id);
        String aHurdlesId = managerAnimal.getAHurdlesId();
        ManagerHurdles managerHurdles = managerHurdlesMapper.selectByPrimaryKey(aHurdlesId);
        Integer hSaved = managerHurdles.getHSaved();
        managerHurdles.setHSaved(hSaved - 1);
        String hFull = managerHurdles.getHFull();
        if ("已满".equals(hFull)) {
            managerHurdles.setHFull("未满");
        }
        managerHurdlesMapper.updateByPrimaryKeySelective(managerHurdles);

        // 删除
        int i = managerAnimalMapper.deleteByPrimaryKey(id);
        if (i == 0) {
            throw new ServiceException(ResultCode.FAIL + "删除动物信息失败");
        }
    }

    @Override
    @Transactional
    public void removeBatch(List<String> ids) {
        ids.forEach((id) -> {
            // 删除时修改动物所属栏圈的容量减一，原来已满，修改为未满
            ManagerAnimal managerAnimal = managerAnimalMapper.selectByPrimaryKey(id);
            String aHurdlesId = managerAnimal.getAHurdlesId();
            ManagerHurdles managerHurdles = managerHurdlesMapper.selectByPrimaryKey(aHurdlesId);
            Integer hSaved = managerHurdles.getHSaved();
            managerHurdles.setHSaved(hSaved - 1);
            String hFull = managerHurdles.getHFull();
            if ("已满".equals(hFull)) {
                managerHurdles.setHFull("未满");
            }
            managerHurdlesMapper.updateByPrimaryKeySelective(managerHurdles);
        });

        // 删除
        ManagerAnimalExample managerAnimalExample = new ManagerAnimalExample();
        managerAnimalExample.createCriteria().andAAnimalIdIn(ids);
        int i = managerAnimalMapper.deleteByExample(managerAnimalExample);
        if (i == 0) {
            throw new ServiceException(ResultCode.FAIL + "批量删除动物信息失败");
        }
    }

    @Override
    @Transactional
    public void creatQRcode() {

    }
}
